package com.example.chapter07_client;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.Contacts;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.example.chapter07_client.Util.PermissionUtil;
import com.example.chapter07_client.Util.ToastUtil;
import com.example.chapter07_client.entity.Contact;

import java.util.ArrayList;

public class ContactAddActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String[] PERMISSIONS = {
            Manifest.permission.WRITE_CONTACTS,
            Manifest.permission.READ_CONTACTS
    };

    private static final int REQUEST_CONTACT_PERMISSION = 1;
    private static final String TAG = "liu";

    private EditText et_contact_name;
    private EditText et_contact_phone;
    private EditText et_contact_email;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contact_add);

        et_contact_name = findViewById(R.id.et_contact_name);
        et_contact_phone = findViewById(R.id.et_contact_phone);
        et_contact_email = findViewById(R.id.et_contact_email);

        findViewById(R.id.btn_add_contact).setOnClickListener(this);
        findViewById(R.id.btn_read_contact).setOnClickListener(this);

        PermissionUtil.checkPermission(this, PERMISSIONS, REQUEST_CONTACT_PERMISSION);

    }

    @Override
    public void onClick(View v) {
        String contact_name = et_contact_name.getText().toString();
        String contact_phone = et_contact_phone.getText().toString();
        String contact_email = et_contact_email.getText().toString();
        if (v.getId() == R.id.btn_add_contact) {
            boolean contactPermission = PermissionUtil.checkPermission(this, PERMISSIONS,
                    REQUEST_CONTACT_PERMISSION);
            if (!contactPermission) {
                ToastUtil.show(this, "当前没有联系人读写权限");
                Log.d(TAG, "当前App没有联系人读写权限");
                return;
            }

            //创建一个联系人对象
            Contact contact = new Contact();
            contact.setName(contact_name);
            contact.setEmail(contact_email);
            contact.setPhone(contact_phone);


            //方式一，使用ContentResolver多次写入，每次一个字段
            //第一种方式有弊端：因为可能姓名添加了，但是电话号码添加失败，可以用事务来解决
            //addContacts(getContentResolver(), contact);
            //ToastUtil.show(this,"添加成功");

            //方式二，批处理方式
            //每一次操作都是一个 ContentProviderOperation,构建一个操作集合，然后一次性执行
            //好处是，要么全部成功，要么全部失败，保证了事务的一致性
            addFullContacts(getContentResolver(), contact);
            ToastUtil.show(this, "添加成功");
        }

        if (v.getId() == R.id.btn_read_contact) {
            //读取联系人
            //1、判断是否获得权限
            boolean contactPermission = PermissionUtil.checkPermission(this,
                    PERMISSIONS, REQUEST_CONTACT_PERMISSION);
            if (!contactPermission) {
                ToastUtil.show(this, "当前没有联系人读写权限");
                Log.d(TAG, "当前App没有联系人读写权限");
                return;
            }

            //获得权限读取联系人信息
            readContacts(getContentResolver());
        }
    }

    @SuppressLint({"Range", "Recycle"})
    private void readContacts(ContentResolver resolver) {
        //先查raw_contacts表，根据raw_contacts_id去查询data表
        Cursor cursor = resolver.query(Contacts.CONTENT_URI, new String[]{ContactsContract.RawContacts._ID}, null,
                null, null);
        if (cursor == null) {
            ToastUtil.show(this, "查询失败");
            return;
        }
        while (cursor.moveToNext()) {
            int rawContactId = cursor.getInt(0);
            Uri uri = Uri.parse("content://com.android.contacts/contacts/" + rawContactId + "/data");
            Cursor dataCursor = resolver.query(uri, new String[]{Contacts.Data.MIMETYPE,
                            Contacts.Data.DATA1, Contacts.Data.DATA2},
                    null, null, null);

            if (dataCursor == null) {
                ToastUtil.show(this, "查询失败");
                return;
            }
            Contact contact = new Contact();
            while (dataCursor.moveToNext()) {
                String data1 = dataCursor.
                        getString(dataCursor.getColumnIndex(Contacts.Data.DATA1));
                String MimeType = dataCursor.
                        getString(dataCursor.getColumnIndex(Contacts.Data.MIMETYPE));

                switch (MimeType) {
                        //是姓名
                    case CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE:
                        contact.setName(data1);
                        //电话号码
                    case CommonDataKinds.Phone.CONTENT_ITEM_TYPE:
                        contact.setPhone(data1);
                        //邮箱
                    case CommonDataKinds.Email.CONTENT_ITEM_TYPE:
                        contact.setEmail(data1);

                }
            }
            dataCursor.close();
            //RawContacts表中出现的_id,不一定在data表中会有记录
            if(contact.getName()!=null){
                Log.d(TAG,contact.toString());
            }
        }
        cursor.close();
    }

    private void addFullContacts(ContentResolver resolver, Contact contact) {
        //创建一个插入联系人主记录的内容操作器
        ContentProviderOperation op_main = ContentProviderOperation.
                newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null) //这一行代码是为了防止报空指针异常
                .build();

        //创建一个插入联系人姓名的内容操作器
        ContentProviderOperation op_name = ContentProviderOperation
                .newInsert(ContactsContract.Data.CONTENT_URI)
                //将第0个操作的id，即raw_contacts的id作为data表中的raw_contacts_id
                .withValueBackReference(Contacts.Data.RAW_CONTACT_ID, 0)
                .withValue(Contacts.Data.MIMETYPE, CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                .withValue(Contacts.Data.DATA2, contact.getName())
                .build();

        //创建一个插入电话号码的内容操作器
        ContentProviderOperation op_phone = ContentProviderOperation
                .newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(Contacts.Data.RAW_CONTACT_ID, 0)
                .withValue(Contacts.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                .withValue(Contacts.Data.DATA1, contact.getPhone())
                .withValue(Contacts.Data.DATA2, CommonDataKinds.Phone.TYPE_WORK)
                .build();

        //创建一个电子邮箱的内容操作器
        ContentProviderOperation op_email = ContentProviderOperation
                .newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(Contacts.Data.RAW_CONTACT_ID, 0)
                .withValue(Contacts.Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE)
                .withValue(Contacts.Data.DATA1, contact.getEmail())
                .withValue(Contacts.Data.DATA2, CommonDataKinds.Email.TYPE_WORK)
                .build();

        //声明一个内容操作器的列表，把上述四个操作添加到该列表中
        ArrayList<ContentProviderOperation> operations = new ArrayList<>();
        operations.add(op_main);
        operations.add(op_name);
        operations.add(op_phone);
        operations.add(op_email);

        try {
            //批量提交四个操作
            resolver.applyBatch(ContactsContract.AUTHORITY, operations);
        } catch (OperationApplicationException | RemoteException e) {
            Log.e(TAG, "插入失败");
        }


    }

    //往手机通讯录中添加一个联系人信息（姓名，电话，电子邮箱）
    private void addContacts(ContentResolver resolver, Contact contact) {
        ContentValues values = new ContentValues();
        //往 raw_contacts 添加联系人记录，并获取添加后的联系人编号
        Uri uri = resolver.insert(ContactsContract.RawContacts.CONTENT_URI, values);

        if (uri == null) {
            Log.e(TAG, "insert raw_contacts failed");
            return;
        }
        long rawContactId = ContentUris.parseId(uri);

        //往Data表中插入数据
        ContentValues name = new ContentValues();
        //关联联系人编号
        name.put(Contacts.Data.RAW_CONTACT_ID, rawContactId);
        //姓名的数据类型
        name.put(Contacts.Data.MIMETYPE, CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        //联系人的姓名
        name.put(Contacts.Data.DATA2, contact.getName());
        //往提供器添加联系人的姓名记录
        resolver.insert(ContactsContract.Data.CONTENT_URI, name);

        ContentValues phone = new ContentValues();
        //关联联系人编号
        phone.put(Contacts.Data.RAW_CONTACT_ID, rawContactId);
        //联系人的电话号码的数据类型
        phone.put(Contacts.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        //电话号码
        phone.put(Contacts.Data.DATA1, contact.getPhone());
        //联系类型 1表示家庭 2表示工作
        phone.put(Contacts.Data.DATA2, CommonDataKinds.Phone.TYPE_WORK);
        //往提供器添加联系人的电话号码记录
        resolver.insert(ContactsContract.Data.CONTENT_URI, phone);


        ContentValues email = new ContentValues();
        //关联联系人编号
        email.put(Contacts.Data.RAW_CONTACT_ID, rawContactId);
        //联系人的邮箱的数据类型
        email.put(Contacts.Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE);
        //电子邮箱
        email.put(Contacts.Data.DATA1, contact.getEmail());
        //电子邮箱类型：1表示家庭 2表示工作
        email.put(Contacts.Data.DATA2, CommonDataKinds.Email.TYPE_WORK);
        //往提供器添加联系人的电子信息记录
        resolver.insert(ContactsContract.Data.CONTENT_URI, email);

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CONTACT_PERMISSION) {
            if (PermissionUtil.checkGrant(grantResults)) {
                Log.d(TAG, "联系人读写权限获取成功");
                return;
            }
            for (int grantResult : grantResults) {
                if (grantResult != PackageManager.PERMISSION_GRANTED) {
                    ToastUtil.show(this, "联系人读写权限获取失败");
                    jumpToSettings();
                    break;
                }
            }
        }
    }

    private void jumpToSettings() {
        Intent intent = new Intent();
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.fromParts("package", getPackageName(), null));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
}